package com.log4jviewer.ui.preferences.additional;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jface.preference.IPreferenceStore;

/**
 * Class provides list of column preference model. Provides method to work with preference model content.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a>
 */
public final class ColumnModelList {

    private static Set<ColumnModelListListener> listeners = new HashSet<ColumnModelListListener>();

    private ColumnModel[] columnItems;

    public ColumnModelList(final IPreferenceStore store) {
        columnItems = loadColumnPrefs(store);
    }

    public ColumnModel[] getColumnItems() {
        return columnItems;
    }

    private ColumnModel[] loadColumnPrefs(final IPreferenceStore store) {
        int columnItemsNum = LogFieldColumn.values().length;
        ColumnModel[] columnItems = new ColumnModel[columnItemsNum];
        final int columnIndexId = 0;
        final int columnWidthId = 1;
        final int isColumnDisplayId = 2;

        for (int i = 0; i < columnItemsNum; i++) {
            String prefs = store.getString(LogFieldColumn.values()[i].getId());
            String[] prefsList = prefs.split(LogFieldColumn.SEPARATOR);

            int columnIndex = Integer.parseInt(prefsList[columnIndexId]);
            int columnWidth = Integer.parseInt(prefsList[columnWidthId]);
            boolean isColumnDisplay = Boolean.parseBoolean(prefsList[isColumnDisplayId]);

            columnItems[i] = new ColumnModel(columnIndex, columnWidth, isColumnDisplay);
        }

        return columnItems;
    }

    public void moveUp(final int pos) {
        if ((pos > 0) && (pos < columnItems.length)) {
            swapColumns(pos, pos - 1);
        }
    }

    public void moveDown(final int pos) {
        if ((pos >= 0) && (pos < (columnItems.length - 1))) {
            swapColumns(pos, pos + 1);
        }
    }

    private void swapColumns(final int pos, final int nextPos) {
        ColumnModel tempColItem = columnItems[nextPos];
        columnItems[nextPos] = columnItems[pos];
        columnItems[pos] = tempColItem;

        // Notify observers about swapping columns.
        notifyListeners(this, new int[] { pos, nextPos });
    }

    public static void notifyListeners(final ColumnModelList event, final int[] swappingColumnIndexes) {
        for (ColumnModelListListener listener : listeners) {
            listener.handleColumnModelListEvent(event, swappingColumnIndexes);
        }
    }

    public static void addListener(final ColumnModelListListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }

    public static void removeListener(final ColumnModelListListener listener) {
        listeners.remove(listener);
    }
}
